package org.example.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.micrometer.common.util.StringUtils;
import jakarta.servlet.http.HttpSession;
import org.example.reggie.dto.UserDto;
import org.example.reggie.entry.User;
import org.example.reggie.result.ResultData;
import org.example.reggie.service.UserService;
import org.example.reggie.utils.ValidateCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 客户端用户信息 controller控制类
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CacheManager cacheManager;

    /**
     * CachePut:将方法返回值放入到缓存
     * value:缓存名称，每个缓存下面可以有多个key
     * key：缓存的key
     * @param user
     * @return
     */
    @CachePut(value="userCache",key = "#result.user.id")
    @PostMapping("/save")
    public ResultData<User> save(@RequestBody User user){
        userService.save(user);
        return ResultData.success("保存成功",user);
    }

    /**
     * 更新
     * @param user
     * @return
     */
    @CachePut(value="userCache",key = "#user.id")
    @PostMapping("/update")
    public ResultData<User> update(@RequestBody User user){
        userService.updateById(user);
        return ResultData.success("更新成功",user);
    }

    /**
     * 删除数据，同时删除缓存中的数据
     * @param id
     * @return
     */
    @CacheEvict(value="userCache",key="#id")
    @DeleteMapping("/delete")
    public ResultData<String> delete(@PathVariable Long id){
        userService.removeById(id);
        return ResultData.success("删除成功");
    }

    @CacheEvict(value="userCache",key="#id")
    @GetMapping("/getById")
    public ResultData<User> getById(@PathVariable Long id) {
        User user=userService.getById(id);
        return ResultData.success(user);
    }

    /**
     * 列表查询，#user.id中的user来自于参数
     * @param user
     * @return
     */
    @CachePut(value="userCache",key = "#user.id+'_'+#user.name")
    @GetMapping("/list")
    public ResultData<List> getList(@RequestBody User user){
        LambdaQueryWrapper<User> queryWrapper =new LambdaQueryWrapper<>();
        queryWrapper.eq(null!=user.getName(),User::getName,user.getName());
        queryWrapper.eq(null!=user.getId(),User::getId,user.getId());
        List<User> list = userService.list(queryWrapper);
        return ResultData.success(list);
    }

    /**
     * 模拟发送短信
     * @param user
     * @return
     */
    @PostMapping("/sendMsg")
    public ResultData<String> sendMsg(@RequestBody User user) {
        //获取手机号
        String userPhone = user.getPhone();
        //判断手机号是否为空
        if (StringUtils.isNotEmpty(userPhone)) {
            //利用验证码生成类来生成验证码
            String code = ValidateCodeUtils.generateValidateCode4String(4);
            //将验证码存入redis，并设置好失效时间为5分钟
            redisTemplate.opsForValue().set(userPhone, code, 5, TimeUnit.MINUTES);
            return ResultData.success("验证码发送成功，有效时间为5分钟");
        }
        return ResultData.error("验证码发送失败");
    }

    /**
     * 登录
     * @param userDto
     * @param codeInSession
     * @return
     */
    @PostMapping("/login")
    public ResultData<String> login(@RequestBody UserDto userDto, HttpSession codeInSession) {
        //拿到验证码和手机号
        String code = userDto.getCode();
        String phone = userDto.getPhone();
        //从Redis中拿验证
        String tempCode = (String) redisTemplate.opsForValue().get(phone);
        //验证码相等
        if (code.equals(tempCode) && codeInSession != null) {
            //是否为新用户，如果是新用户顺手注册了
            LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(User::getPhone, phone);
            //只能用getOne来匹配，不能用getById，因为没有Id给你匹配，都是空的
            User user = userService.getOne(lambdaQueryWrapper);
            if (user==null){
                user = new User();
                user.setPhone(phone);
                user.setStatus(1);
                userService.save(user);
            }
            //此时已经登陆成功，向Redis中存入userId的信息留给过滤器进行验证放行
            redisTemplate.opsForValue().set("user", user.getId());
            //再删掉验证码
            redisTemplate.delete(phone);
            return ResultData.success("登陆成功，欢迎~");
        }
        return ResultData.error("验证码错误");
    }
}
